class TDXFunctions:
    """通达信常用函数工具类"""

    def HHV(self, data, period):
        """计算周期内最高值"""
        try:
            # 获取数据
            values = data.get(ago=0, size=period)
            
            # 检查是否有数据
            if not values or len(values) == 0:
                # 如果没有数据，返回当前值或0
                return data[0] if len(data) > 0 else 0
            
            # 如果数据不足周期数，使用现有数据
            if len(values) < period:
                return max(values)
            
            # 正常情况返回最大值
            return max(values)
        except Exception as e:
            print(f"HHV计算错误: {e}")
            # 出错时返回当前值或0
            return data[0] if len(data) > 0 else 0
    
    def LLV(self, data, period):
        """计算周期内最低值"""
        try:
            # 获取数据
            values = data.get(ago=0, size=period)
            
            # 检查是否有数据
            if not values or len(values) == 0:
                # 如果没有数据，返回当前值或0
                return data[0] if len(data) > 0 else 0
            
            # 如果数据不足周期数，使用现有数据
            if len(values) < period:
                return min(values)
            
            # 正常情况返回最小值
            return min(values)
        except Exception as e:
            print(f"LLV计算错误: {e}")
            # 出错时返回当前值或0
            return data[0] if len(data) > 0 else 0
    
    @staticmethod
    def CROSS(data1, data2=None):
        """交叉函数 - 判断data1从下方向上穿过data2"""
        if data2 is None:
            # 如果只传入一个参数，假设施传入的是数值对(前值, 当前值)
            if isinstance(data1, tuple) and len(data1) == 4:
                a_prev, a_curr, b_prev, b_curr = data1
                return (a_prev < b_prev) and (a_curr >= b_curr)
            return False
        
        if len(data1) < 2 or len(data2) < 2:
            return False
        return (data1[-2] < data2[-2]) and (data1[-1] >= data2[-1])
    
    @staticmethod
    def CROSS_simple(a_prev, a_curr, b_prev, b_curr):
        """简化版交叉函数，用于数值比较"""
        return (a_prev < b_prev) and (a_curr >= b_curr)
    
    @staticmethod
    def FILTER(signals, period):
        """
        过滤函数 - 在指定周期内，同一个条件只能成立一次
        返回过滤后的完整信号列表
        """
        if len(signals) == 0:
            return []
        
        filtered_signals = [False] * len(signals)
        
        # 从前往后处理每个信号
        for i in range(len(signals)):
            if not signals[i]:
                continue
            
            # 检查从当前位置往前推period周期内是否已经有True信号
            start_idx = max(0, i - period + 1)
            has_recent_true = False
            
            for j in range(start_idx, i):
                if filtered_signals[j]:
                    has_recent_true = True
                    break
            
            # 如果在指定周期内没有其他True信号，则当前信号成立
            if not has_recent_true:
                filtered_signals[i] = True
        
        return filtered_signals
    
    @staticmethod
    def BARSLAST(condition_signals):
        """
        上一次条件成立距今的周期数
        返回距离最近一次True信号的周期数（从0开始）
        """
        if len(condition_signals) == 0:
            return 0
        
        # 从后往前查找最近的True信号
        for i in range(len(condition_signals)):
            idx = len(condition_signals) - 1 - i
            if condition_signals[idx]:
                return i
        return len(condition_signals)  # 如果从未找到，则返回最大距离
    
    @staticmethod
    def REF(data, periods):
        """
        引用函数 - 引用若干周期前的数据
        periods: 周期数（正数表示往前推）
        """
        if len(data) <= periods or periods < 0:
            return data[0] if len(data) > 0 else 0
        return data[-periods] if periods > 0 else data[0]
    
    @staticmethod
    def EMA(data, period):
        """指数移动平均函数"""
        if len(data) < period:
            if len(data) == 0:
                return 0
            # 简单平均作为初始值
            return sum(data) / len(data)
        
        # 计算EMA
        alpha = 2 / (period + 1)
        ema_values = []
        data_values = data.get(ago=0, size=period) if hasattr(data, 'get') else data[-period:]
        
        for i in range(len(data_values)):
            if i == 0:
                ema_values.append(data_values[0])
            else:
                ema_values.append(alpha * data_values[i] + (1 - alpha) * ema_values[-1])
        return ema_values[-1] if ema_values else 0
    
    @staticmethod
    def COUNT(condition_list, period):
        """统计周期内满足条件的次数"""
        if len(condition_list) < period:
            return sum(condition_list)
        return sum(condition_list[-period:])
    
    @staticmethod
    def SMA(data, period, weight=1):
        """
        通达信SMA函数实现
        SMA(X,N,M): (M*X+(N-M)*昨日SMA)/N
        """
        if len(data) < period:
            return []
        
        result = []
        
        # 计算第一个SMA值（简单平均）
        initial_sum = 0
        for i in range(period):
            initial_sum += data[i]
        initial_sma = initial_sum / period
        result.append(initial_sma)
        
        # 计算后续SMA值
        for i in range(period, len(data)):
            prev_sma = result[-1]
            current_value = data[i]
            # SMA公式: (M*当前值 + (N-M)*前一个SMA) / N
            sma_value = (weight * current_value + (period - weight) * prev_sma) / period
            result.append(sma_value)
        
        return result
    
    @staticmethod
    def MA(data, period):
        """简单移动平均"""
        if len(data) < period:
            return []
        
        result = []
        for i in range(period - 1, len(data)):
            sum_val = 0
            for j in range(i - period + 1, i + 1):
                sum_val += data[j]
            result.append(sum_val / period)
        
        return result